#include "tmp100_driver.h"

#define TMP100_SD_SET                0x01 /*!< Set SD bit in the configuration register */
#define TMP100_SD_RESET              0xFE /*!< Reset SD bit in the configuration register */
  
__IO uint32_t  TMP100_Timeout = TMP100_LONG_TIMEOUT; 

static void TMP100_DMA_Config(TMP100_DMADirection_TypeDef Direction, uint8_t* buffer, uint8_t NumData);

/**
  * @brief  DeInitializes the TMP100_I2C.
  * @param  None
  * @retval None
  */
void TMP100_DeInit(void)
{
  TMP100_LowLevel_DeInit();
}

/**
  * @brief  Initializes the TMP100_I2C.
  * @param  None
  * @retval None
  */
void TMP100_Init(void)
{
  I2C_InitTypeDef   I2C_InitStructure;
  
  TMP100_LowLevel_Init();
  
  I2C_DeInit(TMP100_I2C);

  /*!< TMP100_I2C Init */
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStructure.I2C_OwnAddress1 = 0x00;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_ClockSpeed = TMP100_I2C_SPEED;
  I2C_Init(TMP100_I2C, &I2C_InitStructure);

  /*!< TMP100_I2C Init */
  I2C_Cmd(TMP100_I2C, ENABLE);
}


/**
  * @brief  Configure the DMA Peripheral used to handle communication via I2C.
  * @param  None
  * @retval None
  */

static void TMP100_DMA_Config(TMP100_DMADirection_TypeDef Direction, uint8_t* buffer, uint8_t NumData)
{
  DMA_InitTypeDef DMA_InitStructure;
  
  RCC_AHBPeriphClockCmd(TMP100_DMA_CLK, ENABLE);
  
  /* Initialize the DMA_PeripheralBaseAddr member */
  DMA_InitStructure.DMA_PeripheralBaseAddr = TMP100_I2C_DR;
  /* Initialize the DMA_MemoryBaseAddr member */
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)buffer;
   /* Initialize the DMA_PeripheralInc member */
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  /* Initialize the DMA_MemoryInc member */
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  /* Initialize the DMA_PeripheralDataSize member */
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  /* Initialize the DMA_MemoryDataSize member */
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  /* Initialize the DMA_Mode member */
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  /* Initialize the DMA_Priority member */
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  /* Initialize the DMA_M2M member */
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  
  /* If using DMA for Reception */
  if (Direction == TMP100_DMA_RX)
  {
    /* Initialize the DMA_DIR member */
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    
    /* Initialize the DMA_BufferSize member */
    DMA_InitStructure.DMA_BufferSize = NumData;
    
    DMA_DeInit(TMP100_DMA_RX_CHANNEL);
    
    DMA_Init(TMP100_DMA_RX_CHANNEL, &DMA_InitStructure);
  }
   /* If using DMA for Transmission */
  else if (Direction == TMP100_DMA_TX)
  { 
    /* Initialize the DMA_DIR member */
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    
    /* Initialize the DMA_BufferSize member */
    DMA_InitStructure.DMA_BufferSize = NumData;
    
    DMA_DeInit(TMP100_DMA_TX_CHANNEL);
    
    DMA_Init(TMP100_DMA_TX_CHANNEL, &DMA_InitStructure);
  }
}


/**
  * @brief  Checks the TMP100 status.
  * @param  None
  * @retval ErrorStatus: TMP100 Status (ERROR or SUCCESS).
  */
ErrorStatus TMP100_GetStatus(uint8_t addr)
{
  uint32_t I2C_TimeOut = I2C_TIMEOUT;

  /*!< Clear the TMP100_I2C AF flag */
  I2C_ClearFlag(TMP100_I2C, I2C_FLAG_AF);

  /*!< Enable TMP100_I2C acknowledgement if it is already disabled by other function */
  I2C_AcknowledgeConfig(TMP100_I2C, ENABLE);

  /*---------------------------- Transmission Phase ---------------------------*/

  /*!< Send TMP100_I2C START condition */
  I2C_GenerateSTART(TMP100_I2C, ENABLE);

  /*!< Test on TMP100_I2C EV5 and clear it */
  while ((!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_SB)) && I2C_TimeOut)  /*!< EV5 */
  {
    I2C_TimeOut--;
  }
  if (I2C_TimeOut == 0)
  {
    return ERROR;
  }
  
  I2C_TimeOut = I2C_TIMEOUT;

  /*!< Send STTMP100 slave address for write */
  I2C_Send7bitAddress(TMP100_I2C, addr, I2C_Direction_Transmitter);

  while ((!I2C_CheckEvent(TMP100_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) && I2C_TimeOut)/* EV6 */
  {
    I2C_TimeOut--;
  }

  if ((I2C_GetFlagStatus(TMP100_I2C, I2C_FLAG_AF) != 0x00) || (I2C_TimeOut == 0))
  {
    return ERROR;
  }
  else
  {
    return SUCCESS;
  }
}
/**
  * @brief  Read the specified register from the TMP100.
  * @param  RegName: specifies the TMP100 register to be read.
  *              This member can be one of the following values:  
  *                  - TMP100_REG_TEMP: temperature register
  *                  - TMP100_REG_TOS: Over-limit temperature register
  *                  - TMP100_REG_THYS: Hysteresis temperature register
  * @retval TMP100 register value.
  */
uint16_t TMP100_ReadReg(uint8_t RegName, uint8_t addr)
{   
  uint8_t TMP100_BufferRX[2] ={0,0};
  uint16_t tmp = 0;    
  
   /* Test on BUSY Flag */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while (I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BUSY)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Configure DMA Peripheral */
  TMP100_DMA_Config(TMP100_DMA_RX, (uint8_t*)TMP100_BufferRX, 2);  
  
  /* Enable DMA NACK automatic generation */
  I2C_DMALastTransferCmd(TMP100_I2C, ENABLE);
  
  /* Enable the I2C peripheral */
  I2C_GenerateSTART(TMP100_I2C, ENABLE);
  
  /* Test on SB Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_SB)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send device address for write */
  I2C_Send7bitAddress(TMP100_I2C, addr, I2C_Direction_Transmitter);
  
  /* Test on ADDR Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(TMP100_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send the device's internal address to write to */
  I2C_SendData(TMP100_I2C, RegName);  
  
  /* Test on TXE FLag (data sent) */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while ((!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BTF)))  
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send START condition a second time */  
  I2C_GenerateSTART(TMP100_I2C, ENABLE);
  
  /* Test on SB Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_SB)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send TMP100 address for read */
  I2C_Send7bitAddress(TMP100_I2C, addr, I2C_Direction_Receiver);
  
  /* Test on ADDR Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(TMP100_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))   
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Enable I2C DMA request */
  I2C_DMACmd(TMP100_I2C,ENABLE);
  
  /* Enable DMA RX Channel */
  DMA_Cmd(TMP100_DMA_RX_CHANNEL, ENABLE);
  
  /* Wait until DMA Transfer Complete */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while (!DMA_GetFlagStatus(TMP100_DMA_RX_TCFLAG))
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }        
  
  /* Send STOP Condition */
  I2C_GenerateSTOP(TMP100_I2C, ENABLE);
  
  /* Disable DMA RX Channel */
  DMA_Cmd(TMP100_DMA_RX_CHANNEL, DISABLE);
  
  /* Disable I2C DMA request */  
  I2C_DMACmd(TMP100_I2C,DISABLE);
  
  /* Clear DMA RX Transfer Complete Flag */
  DMA_ClearFlag(TMP100_DMA_RX_TCFLAG);
  
  /*!< Store TMP100_I2C received data */
  tmp = (uint16_t)(TMP100_BufferRX[0] << 8);
  tmp |= TMP100_BufferRX[1];
  
  /* return a Reg value */
  return (uint16_t)tmp;  
}

/**
  * @brief  Write to the specified register of the TMP100.
  * @param  RegName: specifies the TMP100 register to be written.
  *              This member can be one of the following values:    
  *                  - TMP100_REG_TOS: Over-limit temperature register
  *                  - TMP100_REG_THYS: Hysteresis temperature register
  * @param  RegValue: value to be written to TMP100 register.  
  * @retval None
  */
uint8_t TMP100_WriteReg(uint8_t RegName, uint16_t RegValue, uint8_t addr)
{   
  uint8_t TMP100_BufferTX[2] ={0,0};
  TMP100_BufferTX[0] = (uint8_t)(RegValue >> 8);
  TMP100_BufferTX[1] = (uint8_t)(RegValue);
  
  /* Test on BUSY Flag */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while (I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BUSY)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Configure DMA Peripheral */
  TMP100_DMA_Config(TMP100_DMA_TX, (uint8_t*)TMP100_BufferTX, 2);
  
  /* Enable the I2C peripheral */
  I2C_GenerateSTART(TMP100_I2C, ENABLE);
  
  /* Test on SB Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_SB) == RESET) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Transmit the slave address and enable writing operation */
  I2C_Send7bitAddress(TMP100_I2C, addr, I2C_Direction_Transmitter);
  
  /* Test on ADDR Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(TMP100_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Transmit the first address for r/w operations */
  I2C_SendData(TMP100_I2C, RegName);
  
  /* Test on TXE FLag (data sent) */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while ((!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BTF)))  
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Enable I2C DMA request */
  I2C_DMACmd(TMP100_I2C,ENABLE);
  
  /* Enable DMA TX Channel */
  DMA_Cmd(TMP100_DMA_TX_CHANNEL, ENABLE);
  
  /* Wait until DMA Transfer Complete */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while (!DMA_GetFlagStatus(TMP100_DMA_TX_TCFLAG))
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }  
  
  /* Wait until BTF Flag is set before generating STOP */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while (I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BTF))  
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send STOP Condition */
  I2C_GenerateSTOP(TMP100_I2C, ENABLE);
  
  /* Disable DMA TX Channel */
  DMA_Cmd(TMP100_DMA_TX_CHANNEL, DISABLE);
  
  /* Disable I2C DMA request */  
  I2C_DMACmd(TMP100_I2C,DISABLE);
  
  /* Clear DMA TX Transfer Complete Flag */
  DMA_ClearFlag(TMP100_DMA_TX_TCFLAG);
  
  return TMP100_OK;
}

/**
  * @brief  Read Temperature register of TMP100: double temperature value.
  * @param  None
  * @retval TMP100 measured temperature value.
  */
uint16_t TMP100_ReadTemp(uint8_t addr)
{   
  uint8_t TMP100_BufferRX[2] ={0,0};
  uint16_t tmp = 0;
  
  /* Test on BUSY Flag */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while (I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BUSY)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Configure DMA Peripheral */
  TMP100_DMA_Config(TMP100_DMA_RX, (uint8_t*)TMP100_BufferRX, 2);  
  
  /* Enable DMA NACK automatic generation */
  I2C_DMALastTransferCmd(TMP100_I2C, ENABLE);
  
  /* Enable the I2C peripheral */
  I2C_GenerateSTART(TMP100_I2C, ENABLE);
  
  /* Test on SB Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_SB)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send device address for write */
  I2C_Send7bitAddress(TMP100_I2C, addr, I2C_Direction_Transmitter);
  
  /* Test on ADDR Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(TMP100_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send the device's internal address to write to */
  I2C_SendData(TMP100_I2C, TMP100_REG_TEMP);  
  
  /* Test on TXE FLag (data sent) */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while ((!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BTF)))  
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send START condition a second time */  
  I2C_GenerateSTART(TMP100_I2C, ENABLE);
  
  /* Test on SB Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_SB)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send TMP100 address for read */
  I2C_Send7bitAddress(TMP100_I2C, addr, I2C_Direction_Receiver);
  
  /* Test on ADDR Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(TMP100_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))   
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Enable I2C DMA request */
  I2C_DMACmd(TMP100_I2C,ENABLE);
  
  /* Enable DMA RX Channel */
  DMA_Cmd(TMP100_DMA_RX_CHANNEL, ENABLE);
  
  /* Wait until DMA Transfer Complete */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while (!DMA_GetFlagStatus(TMP100_DMA_RX_TCFLAG))
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }        
  
  /* Send STOP Condition */
  I2C_GenerateSTOP(TMP100_I2C, ENABLE);
  
  /* Disable DMA RX Channel */
  DMA_Cmd(TMP100_DMA_RX_CHANNEL, DISABLE);
  
  /* Disable I2C DMA request */  
  I2C_DMACmd(TMP100_I2C,DISABLE);
  
  /* Clear DMA RX Transfer Complete Flag */
  DMA_ClearFlag(TMP100_DMA_RX_TCFLAG);
  
  /*!< Store TMP100_I2C received data */
  tmp = (uint16_t)(TMP100_BufferRX[0] << 8);
  tmp |= TMP100_BufferRX[1];    
  
  /*!< Return Temperature value */
  return (uint16_t)(tmp >> 7);
}

/**
  * @brief  Read the configuration register from the TMP100.
  * @param  None
  * @retval TMP100 configuration register value.
  */
uint8_t TMP100_ReadConfReg(uint8_t addr)
{   
  uint8_t TMP100_BufferRX[2] ={0,0}; 
  
  /* Test on BUSY Flag */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while (I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BUSY)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Configure DMA Peripheral */
  TMP100_DMA_Config(TMP100_DMA_RX, (uint8_t*)TMP100_BufferRX, 2);  
  
  /* Enable DMA NACK automatic generation */
  I2C_DMALastTransferCmd(TMP100_I2C, ENABLE);
  
  /* Enable the I2C peripheral */
  I2C_GenerateSTART(TMP100_I2C, ENABLE);
  
  /* Test on SB Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_SB)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send device address for write */
  I2C_Send7bitAddress(TMP100_I2C, addr, I2C_Direction_Transmitter);
  
  /* Test on ADDR Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(TMP100_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send the device's internal address to write to */
  I2C_SendData(TMP100_I2C, TMP100_REG_CONF);  
  
  /* Test on TXE FLag (data sent) */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while ((!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BTF)))  
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send START condition a second time */  
  I2C_GenerateSTART(TMP100_I2C, ENABLE);
  
  /* Test on SB Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_SB)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send TMP100 address for read */
  I2C_Send7bitAddress(TMP100_I2C, addr, I2C_Direction_Receiver);
  
  /* Test on ADDR Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(TMP100_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))   
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Enable I2C DMA request */
  I2C_DMACmd(TMP100_I2C,ENABLE);
  
  /* Enable DMA RX Channel */
  DMA_Cmd(TMP100_DMA_RX_CHANNEL, ENABLE);
  
  /* Wait until DMA Transfer Complete */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while (!DMA_GetFlagStatus(TMP100_DMA_RX_TCFLAG))
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }        
  
  /* Send STOP Condition */
  I2C_GenerateSTOP(TMP100_I2C, ENABLE);
  
  /* Disable DMA RX Channel */
  DMA_Cmd(TMP100_DMA_RX_CHANNEL, DISABLE);
  
  /* Disable I2C DMA request */  
  I2C_DMACmd(TMP100_I2C,DISABLE);
  
  /* Clear DMA RX Transfer Complete Flag */
  DMA_ClearFlag(TMP100_DMA_RX_TCFLAG);
  
  /*!< Return Temperature value */
  return (uint8_t)TMP100_BufferRX[0];
}

/**
  * @brief  Write to the configuration register of the TMP100.
  * @param  RegValue: sepecifies the value to be written to TMP100 configuration 
  *         register.
  * @retval None
  */
uint8_t TMP100_WriteConfReg(uint8_t RegValue, uint8_t addr)
{   
  uint8_t TMP100_BufferTX = 0;  
  TMP100_BufferTX = (uint8_t)(RegValue);
  
  /* Test on BUSY Flag */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while (I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BUSY)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Configure DMA Peripheral */
  TMP100_DMA_Config(TMP100_DMA_TX, (uint8_t*)(&TMP100_BufferTX), 1);
  
  /* Enable the I2C peripheral */
  I2C_GenerateSTART(TMP100_I2C, ENABLE);
  
  /* Test on SB Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_SB) == RESET) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Transmit the slave address and enable writing operation */
  I2C_Send7bitAddress(TMP100_I2C, addr, I2C_Direction_Transmitter);
  
  /* Test on ADDR Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(TMP100_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Transmit the first address for r/w operations */
  I2C_SendData(TMP100_I2C, TMP100_REG_CONF);
  
  /* Test on TXE FLag (data sent) */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while ((!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BTF)))  
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Enable I2C DMA request */
  I2C_DMACmd(TMP100_I2C,ENABLE);
  
  /* Enable DMA TX Channel */
  DMA_Cmd(TMP100_DMA_TX_CHANNEL, ENABLE);
  
  /* Wait until DMA Transfer Complete */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while (!DMA_GetFlagStatus(TMP100_DMA_TX_TCFLAG))
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }  
  
  /* Wait until BTF Flag is set before generating STOP */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while ((!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BTF)))  
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send STOP Condition */
  I2C_GenerateSTOP(TMP100_I2C, ENABLE);
  
  /* Disable DMA TX Channel */
  DMA_Cmd(TMP100_DMA_TX_CHANNEL, DISABLE);
  
  /* Disable I2C DMA request */  
  I2C_DMACmd(TMP100_I2C,DISABLE);
  
  /* Clear DMA TX Transfer Complete Flag */
  DMA_ClearFlag(TMP100_DMA_TX_TCFLAG);  
  
  return TMP100_OK;
  
}

/**
  * @brief  Enables or disables the TMP100.
  * @param  NewState: specifies the TMP100 new status. This parameter can be ENABLE
  *         or DISABLE.  
  * @retval None
  */
uint8_t TMP100_ShutDown(FunctionalState NewState, uint8_t addr)
{   
  uint8_t TMP100_BufferRX[2] ={0,0};
  uint8_t TMP100_BufferTX = 0;
  __IO uint8_t RegValue = 0;    
  
  /* Test on BUSY Flag */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while (I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BUSY)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Configure DMA Peripheral */
  TMP100_DMA_Config(TMP100_DMA_RX, (uint8_t*)TMP100_BufferRX, 2);  
  
  /* Enable DMA NACK automatic generation */
  I2C_DMALastTransferCmd(TMP100_I2C, ENABLE);
  
  /* Enable the I2C peripheral */
  I2C_GenerateSTART(TMP100_I2C, ENABLE);
  
  /* Test on SB Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_SB)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send device address for write */
  I2C_Send7bitAddress(TMP100_I2C, addr, I2C_Direction_Transmitter);
  
  /* Test on ADDR Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(TMP100_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send the device's internal address to write to */
  I2C_SendData(TMP100_I2C, TMP100_REG_CONF);  
  
  /* Test on TXE FLag (data sent) */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while ((!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BTF)))  
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send START condition a second time */  
  I2C_GenerateSTART(TMP100_I2C, ENABLE);
  
  /* Test on SB Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_SB)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send TMP100 address for read */
  I2C_Send7bitAddress(TMP100_I2C, addr, I2C_Direction_Receiver);
  
  /* Test on ADDR Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(TMP100_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))   
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Enable I2C DMA request */
  I2C_DMACmd(TMP100_I2C,ENABLE);
  
  /* Enable DMA RX Channel */
  DMA_Cmd(TMP100_DMA_RX_CHANNEL, ENABLE);
  
  /* Wait until DMA Transfer Complete */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while (!DMA_GetFlagStatus(TMP100_DMA_RX_TCFLAG))
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }        
  
  /* Send STOP Condition */
  I2C_GenerateSTOP(TMP100_I2C, ENABLE);
  
  /* Disable DMA RX Channel */
  DMA_Cmd(TMP100_DMA_RX_CHANNEL, DISABLE);
  
  /* Disable I2C DMA request */  
  I2C_DMACmd(TMP100_I2C,DISABLE);
  
  /* Clear DMA RX Transfer Complete Flag */
  DMA_ClearFlag(TMP100_DMA_RX_TCFLAG);
  
  /*!< Get received data */
  RegValue = (uint8_t)TMP100_BufferRX[0];
  
  /*---------------------------- Transmission Phase ---------------------------*/
  
  /*!< Enable or disable SD bit */
  if (NewState != DISABLE)
  {
    /*!< Enable TMP100 */
    TMP100_BufferTX = RegValue & TMP100_SD_RESET;
  }
  else
  {
    /*!< Disable TMP100 */
    TMP100_BufferTX = RegValue | TMP100_SD_SET;
  }  
  
  /* Test on BUSY Flag */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while (!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BUSY)) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Configure DMA Peripheral */
  TMP100_DMA_Config(TMP100_DMA_TX, (uint8_t*)(&TMP100_BufferTX), 1);
  
  /* Enable the I2C peripheral */
  I2C_GenerateSTART(TMP100_I2C, ENABLE);
  
  /* Test on SB Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_SB) == RESET) 
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Transmit the slave address and enable writing operation */
  I2C_Send7bitAddress(TMP100_I2C, addr, I2C_Direction_Transmitter);
  
  /* Test on ADDR Flag */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(TMP100_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Transmit the first address for r/w operations */
  I2C_SendData(TMP100_I2C, TMP100_REG_CONF);
  
  /* Test on TXE FLag (data sent) */
  TMP100_Timeout = TMP100_FLAG_TIMEOUT;
  while ((!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BTF)))  
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Enable I2C DMA request */
  I2C_DMACmd(TMP100_I2C,ENABLE);
  
  /* Enable DMA TX Channel */
  DMA_Cmd(TMP100_DMA_TX_CHANNEL, ENABLE);
  
  /* Wait until DMA Transfer Complete */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while (!DMA_GetFlagStatus(TMP100_DMA_TX_TCFLAG))
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }  
  
  /* Wait until BTF Flag is set before generating STOP */
  TMP100_Timeout = TMP100_LONG_TIMEOUT;
  while ((!I2C_GetFlagStatus(TMP100_I2C,I2C_FLAG_BTF)))  
  {
    if((TMP100_Timeout--) == 0) return TMP100_TIMEOUT_UserCallback();
  }
  
  /* Send STOP Condition */
  I2C_GenerateSTOP(TMP100_I2C, ENABLE);
  
  /* Disable DMA TX Channel */
  DMA_Cmd(TMP100_DMA_TX_CHANNEL, DISABLE);
  
  /* Disable I2C DMA request */  
  I2C_DMACmd(TMP100_I2C,DISABLE);
  
  /* Clear DMA TX Transfer Complete Flag */
  DMA_ClearFlag(TMP100_DMA_TX_TCFLAG);  
  
  return TMP100_OK;
}

/**
  * @brief  DeInitializes the TMP100_I2C.
  * @param  None
  * @retval None
  */
void TMP100_LowLevel_DeInit(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;

  /*!< Disable TMP100_I2C */
  I2C_Cmd(TMP100_I2C, DISABLE);
  /*!< DeInitializes the TMP100_I2C */
  I2C_DeInit(TMP100_I2C);
  
  /*!< TMP100_I2C Periph clock disable */
  RCC_APB1PeriphClockCmd(TMP100_I2C_CLK, DISABLE);
    
  /*!< Configure TMP100_I2C pins: SCL */
  GPIO_InitStructure.GPIO_Pin = TMP100_I2C_SCL_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(TMP100_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);

  /*!< Configure TMP100_I2C pins: SDA */
  GPIO_InitStructure.GPIO_Pin = TMP100_I2C_SDA_PIN;
  GPIO_Init(TMP100_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);
}


/**
  * @brief  Initializes the TMP100_I2C..
  * @param  None
  * @retval None
  */
void TMP100_LowLevel_Init(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;

  /*!< TMP100_I2C Periph clock enable */
  RCC_APB1PeriphClockCmd(TMP100_I2C_CLK, ENABLE);
    
  /*!< TMP100_I2C_SCL_GPIO_CLK, TMP100_I2C_SDA_GPIO_CLK 
       and TMP100_I2C_SMBUSALERT_GPIO_CLK Periph clock enable */
  RCC_APB2PeriphClockCmd(TMP100_I2C_SCL_GPIO_CLK | TMP100_I2C_SDA_GPIO_CLK , ENABLE);
  
  /*!< Configure TMP100_I2C pins: SCL */
  GPIO_InitStructure.GPIO_Pin = TMP100_I2C_SCL_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
  GPIO_Init(TMP100_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);

  /*!< Configure TMP100_I2C pins: SDA */
  GPIO_InitStructure.GPIO_Pin = TMP100_I2C_SDA_PIN;
  GPIO_Init(TMP100_I2C_SDA_GPIO_PORT, &GPIO_InitStructure); 
}


/**
  * @}
  */


/**
  * @}
  */


/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
